package com.jlf.starter.advice;

import com.jlf.core.annotation.restful.controller.RestfulController;
import com.jlf.starter.advice.entity.AdviceConstant;
import com.jlf.starter.advice.filter.RequestParameterFilter;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.lang.NonNull;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter;

import java.lang.reflect.Type;
import java.time.LocalDateTime;

/**
 * 请求的输入参数的处理
 *
 * @author wujr
 * 2023/7/13
 * @version 1.0
 * 【变更历史】
 * [wujr 2023/7/13 1.0 新增]
 */
@Slf4j
@ControllerAdvice
public class InputAdvice extends RequestBodyAdviceAdapter {
    private void loadSession(boolean isSupported){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (null == attributes) {
            return;
        }
        attributes.setAttribute(AdviceConstant.Attribute.Request.supported, isSupported, RequestAttributes.SCOPE_REQUEST);
        LocalDateTime beginTime = LocalDateTime.now();
        attributes.setAttribute(AdviceConstant.Attribute.Request.time, beginTime, RequestAttributes.SCOPE_REQUEST);

        if (!isSupported){
            return;
        }
        HttpServletRequest httpRequest = attributes.getRequest();

    }
    @Override
    public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
        Class<?> controller = methodParameter.getDeclaringClass();
        boolean isSupported = controller.isAnnotationPresent(RestfulController.class);
        if(!isSupported) {
            controller = methodParameter.getContainingClass();
            isSupported = controller.isAnnotationPresent(RestfulController.class);
        }

        loadSession(isSupported);
        return isSupported;
    }
    @Override
    @NonNull
    public Object afterBodyRead(@NonNull Object body,
                                @NonNull HttpInputMessage inputMessage,
                                MethodParameter parameter,
                                @NonNull Type targetType,
                                @NonNull Class<? extends HttpMessageConverter<?>> converterType) {
        ReflectionUtils.doWithFields(parameter.getParameterType(), field -> RequestParameterFilter.filter(body, field));
        return body;
    }
}
